#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
#include <arpa/inet.h>
#include <sys/time.h>

#include "configure.h"
#include "macro.h"
#include "function.h"
#include "mysocket.h"
#include "mymemory.h"
#include "thread_pool.h"
#include "logic_socket.h"
#include "crc32.h"

//和进程相关的全局量
pid_t current_pid;
pid_t parent_pid;
int process;//进程相关标志
int stop_event;//关闭标志
//和网络有关的全局量
LogicSocket my_socket;
//和线程池相关
ThreadPool thread_pool;

//和设置标题有关的全局量
size_t argv_need_mem = 0;
size_t env_need_mem  = 0;
int    os_argc;
char** os_argv;
char*  env_mem = NULL;
int    daemonized = 0;//守护进程标记

//int process;
sig_atomic_t reap;//标记子进程状态变化

static void FreeResource();

int main(int argc, char *const *argv) {
	int exitcode = 0;
	
	int stop_event = 0;	
	current_pid = getpid();
	parent_pid = getpid();

	//移动环境变量
	argv_need_mem = 0;
	for(int i=0; i<argc; i++) {
		argv_need_mem += strlen(argv[i])+1;
	}
	env_need_mem = 0;
	for(int i=0; environ[i]; i++) {
		env_need_mem += strlen(environ[i])+1;
	}
	os_argc = argc;
	os_argv = (char **)argv;
	
	//初始化全局变量
	my_log.fd = -1;
 	process = PROCESS_MASTER;
	reap = 0;

	//加载配置文件
	Configure *configure = Configure::GetInstance();
	if(configure->Load("monkey.conf") == false) {
		LogInit();
		LogStderr(0, "配置文件[%s]载入失败，退出!", "monkey.conf");
		exitcode = 2;
		goto lblexit;
	}
	//内存初始化
	MyMemory::GetInstance();

	//CRC32校验算法初始化
	CRC32::GetInstance();
	//日志初始化
	LogInit();
	//初始化信号
	if(InitSignals()!=0) {
		exitcode = 1;
		goto lblexit;
	}
        //初始socket
	if(my_socket.Initialize() == false) {
		exitcode = 1;
		goto lblexit;
	}

	//process = PROCESS_MASTER;
	InitSetProcTitle();
	//SetProcTitle("master process!");
	//
	//创建守护进程
	
	if(configure->GetIntDefault("Daemon", 0) == 1) {
		int daemon_result = Daemon();
		if(daemon_result == -1) {
			exitcode = 1;
			goto lblexit;
		}
		if(daemon_result == 1) {
			FreeResource();
			exitcode = 0;
			return exitcode;
		}
		daemonized = 1;
	}
	//LogStderr(0,"开启守护进程!");
	MasterProcessCycle();
lblexit:
	LogStderr(0, "程序退出，再见!");
	//for(;;)sleep(1);

    	return exitcode;
}

void FreeResource() {
	if(env_mem) {
		delete[] env_mem;
		env_mem = NULL;
	}

	if(my_log.fd != STDERR_FILENO && my_log.fd != -1) {
		close(my_log.fd);
		my_log.fd = -1;
	}
}
